package util;

import constant.Common;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Base64;

/**
 * @author zhanglinfeng
 * @date create in 2024/11/8 11:40
 */
public class PicUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(PicUtil.class);

    /**
     * excel转图片
     *
     * @param filePath     图片路径
     * @param wb           excel
     * @param totalColumns 总列数
     */
    public static void toPic(String filePath, SXSSFWorkbook wb, int totalColumns) {
        //查看支持的字体
//        GraphicsEnvironment ge= GraphicsEnvironment.getLocalGraphicsEnvironment();
//        String[] fa=ge.getAvailableFontFamilyNames();
//        for (String s:fa) {
//            LOGGER.info("------------------------:{}",s);
//        }

        Font font = new Font("Microsoft YaHei Light", Font.PLAIN, 18);
        SXSSFSheet sheet = wb.getSheetAt(0);
        // 创建 FormulaEvaluator 对象来解析公式
        FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
        // 创建一个临时的 BufferedImage 用于测量文本宽度
        BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
        Graphics2D tempGraphics = tempImage.createGraphics();
        tempGraphics.setFont(font);
        FontMetrics fontMetrics = tempGraphics.getFontMetrics();

        int[] columnWidths = new int[totalColumns];
        int rowHeight = fontMetrics.getHeight() + 10;
        // 遍历所有单元格内容，计算最大列宽
        for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
            Row row = sheet.getRow(rowIndex);
            if (row == null) continue;
            for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
                Cell cell = row.getCell(colIndex);
                if (cell != null) {
                    String cellValue = getCellValue(cell, formulaEvaluator);
                    int textWidth = fontMetrics.stringWidth(cellValue) + 20;
                    columnWidths[colIndex] = Math.max(columnWidths[colIndex], textWidth);
                } else {
                    columnWidths[colIndex] = Math.max(columnWidths[colIndex], 100);
                }
            }
        }

        // 计算图像总宽度和总高度
        int imageWidth = 100;
        for (int colWidth : columnWidths) {
            imageWidth += colWidth;
        }
        int imageHeight = (sheet.getLastRowNum() + 1) * rowHeight + 100;
        // 创建最终的 BufferedImage
        BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = image.createGraphics();
        // 设置白色背景
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, imageWidth, imageHeight);
        // 设置字体，确保支持中文
        graphics.setFont(font);
        graphics.setColor(Color.BLACK);
        // 起始坐标
        int startX = 50;
        int startY = 50;
        // 绘制每个单元格的内容和样式
        for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
            Row row = sheet.getRow(rowIndex);
            if (row == null) continue;
            int x = startX;
            for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
                Cell cell = row.getCell(colIndex);
                String cellValue = (cell != null) ? getCellValue(cell, formulaEvaluator) : Common.BLANK;
                // 绘制单元格内容
                graphics.drawString(cellValue, x + 5, startY + rowIndex * rowHeight + rowHeight / 2);
                // 绘制单元格边框
                if (cell != null) {
                    CellStyle cellStyle = cell.getCellStyle();
                    drawCellBorders(graphics, x, startY + rowIndex * rowHeight, columnWidths[colIndex], rowHeight, cellStyle);
                }
                // 移动到下一个单元格的位置
                x += columnWidths[colIndex];
            }
        }
        // 释放资源
        graphics.dispose();
        try {
            wb.close();
            tempGraphics.dispose();
            ImageIO.write(image, "png", new File(filePath));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Base64转图片
     *
     * @param content Base64
     * @return BufferedImage
     * @throws IOException 异常
     */
    public static BufferedImage base64ToPic(String content) throws IOException {
        byte[] contentBytes = Base64.getDecoder().decode(content);
        int length = contentBytes.length;
        for (int i = 0; i < length; ++i) {
            if (contentBytes[i] < 0) {
                contentBytes[i] += (byte) 256;
            }
        }
        ByteArrayInputStream inputStream = new ByteArrayInputStream(contentBytes);
        return ImageIO.read(inputStream);
    }

    /**
     * 图片转Base64
     *
     * @param filePath 文件路径
     * @return String
     */
    public static String toBase64(String filePath) throws IOException {
        File image = new File(filePath);
        FileInputStream inputStream = new FileInputStream(image);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
        }
        inputStream.close();
        outputStream.close();
        return Base64.getEncoder().encodeToString(outputStream.toByteArray());
    }

    private static String getCellValue(Cell cell, FormulaEvaluator formulaEvaluator) {
        return switch (cell.getCellType()) {
            case STRING -> cell.getStringCellValue();
            case NUMERIC -> String.valueOf(cell.getNumericCellValue());
            case BOOLEAN -> String.valueOf(cell.getBooleanCellValue());
            case FORMULA -> {
                CellValue evaluatedValue = formulaEvaluator.evaluate(cell);
                yield switch (evaluatedValue.getCellType()) {
                    case STRING -> evaluatedValue.getStringValue();
                    case NUMERIC -> String.valueOf(evaluatedValue.getNumberValue());
                    case BOOLEAN -> String.valueOf(evaluatedValue.getBooleanValue());
                    default -> Common.BLANK;
                };
            }
            default -> Common.BLANK;
        };
    }

    private static void drawCellBorders(Graphics2D graphics, int x, int y, int width, int height, CellStyle style) {
        // 设置边框颜色为黑色
        graphics.setColor(Color.BLACK);
        // 绘制顶部边框
        if (style.getBorderTop() != BorderStyle.NONE) {
            graphics.drawLine(x, y, x + width, y);
        }
        // 绘制底部边框
        if (style.getBorderBottom() != BorderStyle.NONE) {
            graphics.drawLine(x, y + height, x + width, y + height);
        }
        // 绘制左侧边框
        if (style.getBorderLeft() != BorderStyle.NONE) {
            graphics.drawLine(x, y, x, y + height);
        }
        // 绘制右侧边框
        if (style.getBorderRight() != BorderStyle.NONE) {
            graphics.drawLine(x + width, y, x + width, y + height);
        }
    }

}
